#include "Udp.h"

#ifdef Q_OS_Windows
#include <winsock.h>
#endif
#include <stdarg.h>

Udp::Udp(std::string locIp, int locPort, std::string dstIp, int dstPort)
    : m_strLocIp_(locIp), m_nLocPort_(locPort), m_strDstIp_(dstIp),
      m_nDstPort_(dstPort) {
#ifdef Q_OS_Windows
  WSADATA wd;
  WORD w = MAKEWORD(1, 1);
  WSAStartup(w, &wd);

  m_fdSock_ = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

  char tip[256];
  snprintf(tip, sizeof(tip), "create sock,sock:%d,errno:%d.\n", m_fdSock_,
           WSAGetLastError());
  m_strErrTip_ += tip;

  sockaddr_in src;
  memset(&src, 0, sizeof(src));
  src.sin_family = AF_INET;
  src.sin_port = htons(locPort);
  src.sin_addr.S_un.S_addr == INADDR_ANY;

  int bindret = bind(m_fdSock_, (sockaddr *)&src, sizeof(src));
  snprintf(tip, sizeof(tip), "bind,ret:%d,errno:%d.\n", bindret,
           WSAGetLastError());
  m_strErrTip_ += tip;
#endif
}

Udp::~Udp() {
#ifdef Q_OS_Windows
  closesocket(m_fdSock_);
  WSACleanup();
#endif
}

int Udp::sendTo(std::string dstIp, int dstPort, char *data, int byteLen) {
  int sendret = 0;
#ifdef Q_OS_Windows
  unsigned int nAddr = dstIp == "" ? INADDR_ANY : inet_addr(dstIp.c_str());

  sockaddr_in dst;
  memset(&dst, 0, sizeof(dst));
  dst.sin_family = AF_INET;
  dst.sin_port = htons(dstPort);
  dst.sin_addr.S_un.S_addr = nAddr;

  int len = sizeof(dst);

  sendret = sendto(m_fdSock_, data, byteLen, 0, (sockaddr *)&dst, len);
  char tip[256];
  snprintf(tip, sizeof(tip), "send,ret:%d,errno:%d,addr:%s.\n", sendret,
           WSAGetLastError(), inet_ntoa(dst.sin_addr));
  m_strErrTip_ += tip;

#endif
  return sendret;
}

int Udp::recvFrom(std::string dstIp, int dstPort, char *data, int byteLen) {
  int sendret = 0;
#ifdef Q_OS_Windows
  unsigned int nAddr = dstIp == "" ? INADDR_ANY : inet_addr(dstIp.c_str());

  sockaddr_in dst;
  memset(&dst, 0, sizeof(dst));
  dst.sin_family = AF_INET;
  dst.sin_port = htons(dstPort);
  dst.sin_addr.S_un.S_addr = nAddr;

  int len = sizeof(dst);

  sendret = recvfrom(m_fdSock_, data, byteLen, 0, (sockaddr *)&dst, &len);
  char tip[256];
  snprintf(tip, sizeof(tip), "rcv,ret:%d,errno:%d,addr:%s.\n", sendret,
           WSAGetLastError(), inet_ntoa(dst.sin_addr));
  m_strErrTip_ += tip;

#endif
  return sendret;
}

void Udp::formatTip(char *format, ...) {}
